// RedJey Graphics User Interface Library for J2ME Platform.
// Copyright (C) 2008 Yevgen Krapiva
//
// This library is free software; you can redistribute
// it and/or modify it under the terms of the
// GNU Lesser General Public License as published
// by the Free Software Foundation; either version 3.0
// of the License, or any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this library; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//

package com.incrediblesoft.redjey;

/**
 * @author Yevgen Krapiva<br>
 *         Homepage: http://code.google.com/p/redjey/<br>
 *         Feedback: ykrapiva@gmail.com<br>
 *         Copyright (C) 2008 Yevgen Krapiva<br>
 */

import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.Graphics;
import java.util.Hashtable;

public class CustomImage
{
    public Image image;
    public int x;
    public int y;
    public int width;
    public int height;

    protected int numFramesW, numFramesH;
    protected int frameWidth, frameHeight;
    protected int numFrames;
    protected int framerate;
    protected int currentFrame;
    protected long timeLeft;
    protected Component parent;

    public CustomImage(Image image)
    {
        init(image, 0, 0, image.getWidth(), image.getHeight());
    }

    public CustomImage(Image image, int frameWidth, int frameHeight)
    {
        this(image, frameWidth, frameHeight, 1);
    }

    public CustomImage(Image image, int frameWidth, int frameHeight, int framerate)
    {
        init(image, frameWidth, frameHeight, framerate);
    }

    public CustomImage(Image image, int x, int y, int width, int height)
    {
        init(image, x, y, width, height);
    }

    public CustomImage(CustomImage customImage, int x, int y, int width, int height)
    {
        init(customImage.image, customImage.x + x, customImage.y + y, width, height);
    }

    public CustomImage(Hashtable styleDesc)
    {
        image = UIManager.getImage((String) styleDesc.get("name"));
        int intX, intY, intW, intH;
        int intFW, intFH, intFR;
        String strX = (String) styleDesc.get("x");
        String strY = (String) styleDesc.get("y");
        String strW = (String) styleDesc.get("width");
        String strH = (String) styleDesc.get("height");
        intX = (strX == null) ? 0 : Integer.parseInt(strX);
        intY = (strY == null) ? 0 : Integer.parseInt(strY);
        intW = (strW == null) ? image.getWidth() : Integer.parseInt(strW);
        intH = (strH == null) ? image.getHeight() : Integer.parseInt(strH);

        String strFW = (String) styleDesc.get("frame-width");
        String strFH = (String) styleDesc.get("frame-height");
        String strFR = (String) styleDesc.get("framerate");
        intFW = (strFW == null) ? 0 : Integer.parseInt(strFW);
        intFH = (strFH == null) ? 0 : Integer.parseInt(strFH);
        intFR = (strFR == null) ? 1 : Integer.parseInt(strFR);

        if (intFW > 0 && intFH > 0)
            init(image, intFW, intFH, intFR);
        else
            init(image, intX, intY, intW, intH);
    }

    private void init(Image image, int x, int y, int width, int height)
    {
        this.image = image;
        this.x = x;
        this.y = y;
        this.width = width;
        this.height = height;
    }

    private void init (Image image, int frameWidth, int frameHeight, int framerate)
    {
        init(image, 0, 0, frameWidth, frameHeight);
        this.frameWidth = frameWidth;
        this.frameHeight = frameHeight;
        numFramesW = image.getWidth() / frameWidth;
        numFramesH = image.getHeight() / frameHeight;
        numFrames = numFramesW * numFramesH;
        setFramerate(framerate);
    }

    public int getWidth()
    {
        return width;
    }

    public int getHeight()
    {
        return height;
    }

    public void setFramerate(int framerate)
    {
        this.framerate = framerate;
        timeLeft = 1000 / framerate;
    }

    /**
     * Sets the maximum number of frames. Used when some last frames in sequence are empty.
     * @param numFrames
     */
    public void setNumFrames(int numFrames)
    {
        this.numFrames = numFrames;
    }

    public void tick(int dt)
    {
        if (numFrames > 0 && framerate > 0)
        {
            timeLeft -= dt;
            if (timeLeft <= 0)
            {
                timeLeft = 1000 / framerate;
                currentFrame++;
                if (currentFrame >= numFrames)
                    currentFrame = 0;

                x = currentFrame % numFramesW * frameWidth;
                y = currentFrame / numFramesW * frameHeight;

                if (parent != null)
                    parent.repaint();
            }
        }
    }

    public void paint(Graphics g, int x, int y, int alignment)
    {
        int clipX = g.getClipX();
        int clipY = g.getClipY();
        int clipW = g.getClipWidth();
        int clipH = g.getClipHeight();

        if (alignment != (Graphics.LEFT | Graphics.TOP))
        {
            if ((alignment & Graphics.HCENTER) > 0)
                x -= this.width >> 1;
            else if ((alignment & Graphics.RIGHT) > 0)
                x -= this.width;

            if ((alignment & Graphics.VCENTER) > 0)
                y -= this.height >> 1;
            else if ((alignment & Graphics.BOTTOM) > 0)
                y -= this.height;
        }

        g.clipRect(x, y, this.width, this.height);

        g.drawImage(image, x - this.x, y - this.y, Graphics.LEFT | Graphics.TOP);
  
        g.setClip(clipX, clipY, clipW, clipH);
    }

    public CustomImage clone()
    {
        CustomImage newImage = null;

        if (frameWidth > 0 && frameHeight > 0)
        {
            newImage = new CustomImage(image, frameWidth, frameHeight, framerate);
            newImage.setNumFrames(numFrames);
        }
        else newImage = new CustomImage(image, x, y, width, height);

        return newImage;
    }
}
